﻿using System;
using System.Text;
using System.Collections.Generic;
using System.Linq;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Reflection;

namespace ES.Interceptor.Test32.Net40
{
    [TestClass]
    public class MethodHookTests
    {
        private IMethodHook _hook;
        private MethodInfo _staticSayHelloMethod;
        private MethodInfo _staticSayGoodbyeMethod;
        private MethodInfo _instanceSayHelloMethod;
        private MethodInfo _instanceSayGoodbyeMethod;
        

        [TestInitialize]
        public void SetUp()
        {
            _hook = MethodHookFactory.Create();
            _staticSayHelloMethod = typeof( TestClass ).GetMethod( "StaticSayHello" );
            _staticSayGoodbyeMethod = typeof( TestClass ).GetMethod( "StaticSayGoodbye" );

            _instanceSayHelloMethod = typeof( TestClass ).GetMethod( "InstanceSayHello" );
            _instanceSayGoodbyeMethod = typeof( TestClass ).GetMethod( "InstanceSayGoodbye" );
        }

        #region - Static tests -
        [TestMethod]
        public void StaticMethodHook()
        {
            _hook.Initialize( _staticSayHelloMethod, _staticSayGoodbyeMethod );

            var expected = TestClass.StaticSayGoodbye();

            _hook.Hook();
            var actual = TestClass.StaticSayHello();

            Assert.AreEqual( expected, actual );
        }

        [TestMethod]
        public void StaticMethodUnHook()
        {
            _hook.Initialize( _staticSayHelloMethod, _staticSayGoodbyeMethod );

            var expected = TestClass.StaticSayHello();

            _hook.Hook();
            _hook.UnHook();

            var actual = TestClass.StaticSayHello();

            Assert.AreEqual( expected, actual );
        }
        #endregion

        #region - Instance tests -
        [TestMethod]
        public void InstanceMethodHook()
        {
            var testClass = new TestClass();
            _hook.Initialize( _instanceSayHelloMethod, _instanceSayGoodbyeMethod, testClass );
                        
            var expected = testClass.InstanceSayGoodbye();

            _hook.Hook();
            var actual = testClass.InstanceSayHello();

            Assert.AreEqual( expected, actual );
        }

        [TestMethod]       
        public void InstanceMethodUnHook()
        {
            var testClass = new TestClass();
            _hook.Initialize( _instanceSayHelloMethod, _instanceSayGoodbyeMethod, testClass );
                        
            var expected = testClass.InstanceSayHello();

            _hook.Hook();
            _hook.UnHook();

            var actual = testClass.InstanceSayHello();

            Assert.AreEqual( expected, actual );
        }
        #endregion
    }
}
